/*
 *    Copyright (c) 2018-2025, proj All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are met:
 *
 * Redistributions of source code must retain the above copyright notice,
 * this list of conditions and the following disclaimer.
 * Redistributions in binary form must reproduce the above copyright
 * notice, this list of conditions and the following disclaimer in the
 * documentation and/or other materials provided with the distribution.
 * Neither the name of the proj developer nor the names of its
 * contributors may be used to endorse or promote products derived from
 * this software without specific prior written permission.
 * Author: proj
 */
package com.ykht.proj.activity.service.impl;

import cn.hutool.core.bean.BeanUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.ykht.proj.activity.Enum.ActivityStatusEnum;
import com.ykht.proj.activity.Enum.PlanStatusEnum;
import com.ykht.proj.activity.constant.ActivityConstant;
import com.ykht.proj.activity.constant.CardConstant;
import com.ykht.proj.activity.constant.RedisConstant;
import com.ykht.proj.activity.entity.VActivity;
import com.ykht.proj.activity.entity.VActivityCard;
import com.ykht.proj.activity.entity.VDiscountPlan;
import com.ykht.proj.activity.entity.VInfo;
import com.ykht.proj.activity.mapper.VActivityMapper;
import com.ykht.proj.activity.mq.producer.MsgProducer;
import com.ykht.proj.activity.service.VActivityCardService;
import com.ykht.proj.activity.service.VActivityService;
import com.ykht.proj.activity.service.VOrderService;
import com.ykht.proj.activity.vo.VActivityVo;
import com.ykht.proj.common.core.constant.CommonConstants;
import com.ykht.proj.common.core.constant.SecurityConstants;
import com.ykht.proj.common.core.util.R;
import com.ykht.proj.common.security.util.SecurityUtils;
import com.ykht.proj.comsrv.api.feign.RemoteMsgService;
import com.ykht.proj.comsrv.api.feign.RemoteSubsribeMsgService;
import com.ykht.proj.comsrv.constant.ComConstant;
import com.ykht.proj.comsrv.entity.VSubscribeMsg;
import com.ykht.proj.comsrv.vo.SubscribeMsgActivityNotice;
import com.ykht.proj.coupon.api.feign.RemotePersonService;
import com.ykht.proj.coupon.entity.CnPerson;
import lombok.RequiredArgsConstructor;
import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;
import org.apache.rocketmq.spring.core.RocketMQTemplate;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.rmi.MarshalledObject;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.List;
import java.util.stream.Collectors;

/**
 * 活动表
 *
 * @author csg
 * @date 2021-05-21 14:20:15
 */
@RequiredArgsConstructor
@Slf4j
@Service
public class VActivityServiceImpl extends ServiceImpl<VActivityMapper, VActivity> implements VActivityService {

	private final VActivityMapper vActivityMapper;
	private final VActivityCardService vActivityCardService;
	private final VOrderService vOrderService;
	@Resource
	private RedisTemplate redisTemplate;
	/**
	 * 新增活动表
	 *
	 * @param vActivityVo
	 */
	@Transactional(rollbackFor = Exception.class)
	@Override
	public void addActivity(VActivityVo vActivityVo) {
		Long userId = SecurityUtils.getUserId();
		vActivityVo.setCreateUser(userId);
		vActivityVo.setCreateTime(LocalDateTime.now());
		VActivity activity = BeanUtil.toBean(vActivityVo, VActivity.class);
		this.save(activity);
		activity.setActivityLink("/pages/actives/limit_activities_list?activityId=" + activity.getId());
		this.updateById(activity);
		List<VActivityCard> activityCardList = vActivityVo.getActivityCardList();
		activityCardList.stream().forEach(itme ->{
			itme.setActivityId(activity.getId());
			itme.setStatus(activity.getStatus());
			itme.setStartTime(activity.getStartTime());
			itme.setEndTime(activity.getEndTime());
			itme.setCreateUser(userId);
			itme.setCreateTime(LocalDateTime.now());
		});
		vActivityCardService.saveBatch(activityCardList);
		//放入redis中，订阅消息需要使用
		redisTemplate.opsForSet().add(RedisConstant.ACTIVITY_ID,activity.getId());
	}

	/**
	 * 活动列表 分页查询
	 *
	 * @param page
	 * @param vActivityVo
	 * @return
	 */
	@Override
	public IPage<VActivityVo> getVActivityPage(Page page, VActivityVo vActivityVo) {
		IPage<VActivityVo> iPage = vActivityMapper.getVActivityPage(page, vActivityVo);
		List<VActivityVo> activityVoList = iPage.getRecords();
		if (null != activityVoList && activityVoList.size() > 0){
			List<Long> longList = activityVoList.stream().map(VActivityVo::getId).collect(Collectors.toList());
			List<VActivityVo> purchaseCount = vOrderService.getPurchaseCount(longList);
			if (null != purchaseCount && purchaseCount.size() > 0) {
				activityVoList.stream().forEach(itme ->{
					purchaseCount.stream().forEach(coun ->{
						if (itme.getId().equals(coun.getId())) itme.setPurchaseCount(coun.getPurchaseCount());
					});
				});
				iPage.setRecords(activityVoList);
			}
		}
		return iPage;
	}

	/**
	 * 通过id删除活动表
	 *
	 * @param id
	 */
	@Override
	@Transactional(rollbackFor = Exception.class)
	public void deleteActivity(Long id) {
		this.removeById(id);
		vActivityCardService.remove(Wrappers.lambdaQuery(VActivityCard.class).eq(VActivityCard::getActivityId, id));
	}

	@Resource
	private MsgProducer msgProducer;
	@Resource
	private RemoteSubsribeMsgService remoteSubsribeMsgService;
	@Resource
	private RemotePersonService remotePersonService;


	@Override
	public void sendMq(VActivity vActivity) throws Exception {

		R<List<VSubscribeMsg>> r = remoteSubsribeMsgService.getActivityWillSendList(SecurityConstants.FROM_IN);
		if (r.getCode()== CommonConstants.SUCCESS){
			List<VSubscribeMsg> list = r.getData();
			String perIds = list.stream().map(o->String.valueOf(o.getPersonId())).collect(Collectors.joining(","));
			R<List<CnPerson>> r1 = remotePersonService.byIdsFromIn(perIds, SecurityConstants.FROM_IN);
			if (r1.getCode()==CommonConstants.SUCCESS&&r1.getData()!=null){
				for (VSubscribeMsg o : list) {
					SubscribeMsgActivityNotice notice = new SubscribeMsgActivityNotice();
					notice.setType(ComConstant.SUBSCRIBE_MSG_ACTIVITY_NOTICE);
					notice.setActivityId(vActivity.getId());
					notice.setActivityName(vActivity.getName());
					CnPerson person = r1.getData().stream().filter(oo -> oo.getId().equals(o.getPersonId())).findFirst().get();
					notice.setPersonId(person.getId());
					notice.setOpenId(person.getOpenId());
					//notice.setContent("活动即将开始，请做好准备！");
					notice.setStartTime(vActivity.getStartTime().format((DateTimeFormatter.ISO_LOCAL_DATE_TIME)));
					notice.setEndTime(vActivity.getEndTime().format((DateTimeFormatter.ISO_LOCAL_DATE_TIME)));
					msgProducer.sendMsg(notice);
				}
			}

		}

	}

	/**
	 * 修改活动表
	 *
	 * @param vActivity
	 */
	@Override
	public void updateActivity(VActivity vActivity) {
		log.info("->结束活动{}", vActivity);
		this.updateById(vActivity);
		if (vActivity.getStatus().equals(ActivityStatusEnum.BE_OVERDUE.getValue())){
			UpdateWrapper<VActivityCard> updateWrapper = new UpdateWrapper();
			updateWrapper.lambda().eq(VActivityCard::getActivityId, vActivity.getId())
					.set(VActivityCard::getStatus, vActivity.getStatus())
					.set(VActivityCard::getUpdateUser, vActivity.getUpdateUser())
					.set(VActivityCard::getUpdateTime, LocalDateTime.now());
			vActivityCardService.update(updateWrapper);
		}
	}


	/**
	 * 活动定时任务
	 */
	@Override
	public void activityExpireTask() {
		log.info("->活动任务：活动 自动过期");
		QueryWrapper<VActivity> endQueryWrapper = new QueryWrapper<>();
		endQueryWrapper.lambda().lt(VActivity::getEndTime, LocalDateTime.now())
				.eq(VActivity::getStatus, ActivityStatusEnum.AT_WORK.getValue());
		List<VActivity> endActivityList = this.list(endQueryWrapper);
		if (null != endActivityList && endActivityList.size() > 0){
			List<Long> endActivityIdList = endActivityList.stream().map(VActivity::getId).collect(Collectors.toList());
			UpdateWrapper<VActivity> endUpdateWrapper = new UpdateWrapper();
			endUpdateWrapper.lambda().in(VActivity::getId, endActivityIdList)
					.set(VActivity::getStatus, ActivityStatusEnum.BE_OVERDUE.getValue());
			this.update(endUpdateWrapper);
			log.info("->活动和卡 任务：活动 自动过期");
			UpdateWrapper<VActivityCard> activityCardUpdateWrapper = new UpdateWrapper();
			activityCardUpdateWrapper.lambda().in(VActivityCard::getActivityId, endActivityIdList)
					.set(VActivityCard::getStatus, ActivityStatusEnum.BE_OVERDUE.getValue());;
			vActivityCardService.update(activityCardUpdateWrapper);
		}
		log.info("->活动任务：活动 自动上架");
		QueryWrapper<VActivity> startQueryWrapper = new QueryWrapper<>();
		startQueryWrapper.lambda().lt(VActivity::getStartTime, LocalDateTime.now())
				.ge(VActivity::getEndTime, LocalDateTime.now())
				.eq(VActivity::getStatus, ActivityStatusEnum.TO_START.getValue());
		List<VActivity> startActivityList = this.list(startQueryWrapper);

		if (null != startActivityList && startActivityList.size() > 0){
			List<Long> activityIdList = startActivityList.stream().map(VActivity::getId).collect(Collectors.toList());
			UpdateWrapper<VActivity> endUpdateWrapper = new UpdateWrapper();
			endUpdateWrapper.lambda().in(VActivity::getId, activityIdList)
					.set(VActivity::getStatus, ActivityStatusEnum.AT_WORK.getValue());
			this.update(endUpdateWrapper);
			log.info("->活动和卡 任务：活动 自动上架");
			UpdateWrapper<VActivityCard> activityCardUpdateWrapper = new UpdateWrapper();
			activityCardUpdateWrapper.lambda().in(VActivityCard::getActivityId, activityIdList)
					.set(VActivityCard::getStatus, ActivityStatusEnum.AT_WORK.getValue());;
			vActivityCardService.update(activityCardUpdateWrapper);
		}
	}
}
